package com.ficus.road.maintain.task;

import com.ficus.road.maintain.core.model.*;
import com.ficus.road.maintain.core.model.taskInfo.AbnormalWorkCheckCDRequest;
import com.ficus.road.maintain.core.model.taskInfo.AbnormalWorkCheckRequest;
import com.ficus.road.maintain.dao.FailedThirdRequestDao;
import com.ficus.road.maintain.dao.HitDao;
import com.ficus.road.maintain.service.ZHCDClient;
import com.ficus.road.maintain.service.ZhonghaiClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 重试失败的中海请求
 * @author lijiawei
 * @date 2023/10/8 下午2:22
 */

@Component
@Slf4j
public class RetryFailedRequestTask {

    @Autowired
    private FailedThirdRequestDao failedThirdRequestDao;

    @Autowired
    private ZhonghaiClient zhonghaiClient;

    @Autowired
    private ZHCDClient zhcdClient;

    @Autowired
    private HitDao hitDao;

    // 最大重试次数 3次
    private static final int MAX_RETRY_NUM = 3;

    // 过期时间 3天
    private static final int MAX_RETRY_DAYSPAN = 3;

    // 重试所有失败的第三方请求
    @Scheduled(cron = "0 30 8 * * *", zone = "GMT+8:00")
    public void retryWorkCheckRequest() {
        List<FailedThirdRequest> all = failedThirdRequestDao.findAll();
        log.info("调用中海接口重试第三方请求...");
        all.parallelStream().forEach(req -> retryWorkCheckRequestDetail(req));
    }

    public void retryWorkCheckRequestDetail(FailedThirdRequest request) {

        if (request.getType().equals(AbnormalWorkCheckRequest.typeName)) {
            String taskNum = ((AbnormalWorkCheckRequest) request).getTaskNum();
            String rejectedReason = zhonghaiClient.getReasonFromZhongHaiTaskInfo(taskNum);
            if (rejectedReason != null) {
                Hit hit = hitDao.fetch(taskNum);
                if (ObjectUtils.isNotEmpty(hit) && hit.getAttrs().getStatus().equals(HitStatusEnum.REJECTED) && !rejectedReason.equals("已结案")) {
                    hit.getAttrs().setDescription(rejectedReason);
                    for (HistoryHit historyHit : hit.getList()) {
                        if (historyHit.getAttrs().getStatus().equals(HitStatusEnum.REJECTED)) {
                            historyHit.getAttrs().setDescription(rejectedReason);
                            break;
                        }
                    }
                    hitDao.saveOrUpdate(hit);
                }
                failedThirdRequestDao.deleteById(request.getId());
                log.info("重试调用中海公路接口成功, taskNum = {}", taskNum);
            } else {
                resaveFailedRequest(request);
            }
        } else if (request.getType().equals(AbnormalWorkCheckCDRequest.typeName)) {
            String taskNum = ((AbnormalWorkCheckCDRequest) request).getTaskNum();
            String rejectedReason = zhcdClient.getReasonFromZhongHaiCDTaskInfo(taskNum.substring(12));
            if (rejectedReason != null) {
                Hit hit = hitDao.fetch(taskNum);
                if (ObjectUtils.isNotEmpty(hit) && hit.getAttrs().getStatus().equals(HitStatusEnum.REJECTED)) {
                    hit.getAttrs().setDescription(rejectedReason);
                    for (HistoryHit historyHit : hit.getList()) {
                        if (historyHit.getAttrs().getStatus().equals(HitStatusEnum.REJECTED)) {
                            historyHit.getAttrs().setDescription(rejectedReason);
                            break;
                        }
                    }
                    hitDao.saveOrUpdate(hit);
                }
                failedThirdRequestDao.deleteById(request.getId());
                log.info("重试调用中海城道接口成功, taskNum = {}", taskNum);
            } else
                resaveFailedRequest(request);
        }
    }

    private void resaveFailedRequest(FailedThirdRequest request) {
        request.setRetryTime(request.getRetryTime() + 1);
        if (requestExceededLimit(request)) {
            failedThirdRequestDao.deleteById(request.getId());
        } else
            failedThirdRequestDao.saveOrUpdate(request);
    }

    /**
     * 判断请求重试次数是否超过限制
     * @param request
     * @return
     */
    public boolean requestExceededLimit(FailedThirdRequest request) {
        if (request.getRetryTime() >= MAX_RETRY_NUM) {
            return true;
        }
        return false;
    }

}
